package org.zy.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import org.zy.core.MessageDecoder;
import org.zy.core.MessageEncoder;

public class ClientServer {
    private static EventLoopGroup bossGroup = new NioEventLoopGroup();
    private static EventLoopGroup workGroup = new NioEventLoopGroup();

    private static ChannelFuture channelFuture;

    public static void start() throws InterruptedException {
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            ChannelPipeline pipeline = socketChannel.pipeline();
                            pipeline.addLast(new MessageDecoder(Integer.MAX_VALUE, 0, 4, -4, 0));
                            pipeline.addLast(new MessageEncoder());
                            pipeline.addLast(new IdleStateHandler(40, 10, 0));
                            pipeline.addLast(new ClientHandler());
                        }
                    });
            channelFuture = bootstrap.bind(Config.serverPort).sync();

            channelFuture.addListener((ChannelFutureListener) channelFuture -> {
                System.out.println("Server start");
            });

            channelFuture.channel().closeFuture().sync();
        } finally {
            shutdown();
        }
    }

    public static void shutdown() {
        if (null != channelFuture) {
            channelFuture.channel().close().syncUninterruptibly();
        }

        if (null != bossGroup && !bossGroup.isShutdown()) {
            bossGroup.shutdownGracefully();
        }

        if (null != workGroup && !workGroup.isShutdown()) {
            workGroup.shutdownGracefully();
        }

        System.out.println("Server close");
    }
}
